//
//  WBStatusListViewModel.swift
//  simpleWeibo
//
//  Created by 孙林 on 2018/1/20.
//  Copyright © 2018年 孙林. All rights reserved.
//

import Foundation
import SDWebImage


///微博数据列表视图模型
/*
 父类的选择
 -如果类需要用到'KVC'或者字典转模型框架设置对象值 需要集成自NSObject
 -如果只是包装一些代码逻辑(写了一些函数), 不需要集成自NSObject, 更轻量级
 -oc重写,一律直接集成自NSObject就行
 */

private let maxPullupTryTimes = 3

class WBStatusListViewModel {
    ///微博模型数组 懒加载
    lazy var status = [WBStatusViewModel]()
    ///上拉刷新错误次数
    private var pullupErrorTimes = 0
    
    /// 加载微博列表
    ///
    /// - Parameter completion: 完成回调:网路请求是否成功
    func loadStatus(pullup: Bool, completion:@escaping (_ isSuccess: Bool, _ shouldRefresh: Bool)->()) {
        //处理是上拉还是下拉, since_id 和 max_id
        let since_id = pullup ? 0 : (status.first?.status.id ?? 0)
        let max_id = !pullup ? 0 : (status.last?.status.id ?? 0)
        
        WBNetWorkManager.shared.statusList(since_id: since_id, max_id: max_id) { (json, isSuccess) in
            
            //判断是否上拉刷新, 同时上拉刷新错误次数达到3
            if pullup && self.pullupErrorTimes >= maxPullupTryTimes {
                completion(isSuccess, false)
                return
            }
            
            //判断网络请求是否成功
            if !isSuccess {
                //直接回调返回
                completion(false, false)
                return
            }
            
            //1字典转模型
            var array = [WBStatusViewModel]()
            
            //2遍历服务器返回的字典模型数组 字典转模型
            for dict in json ?? [] {
                //a) 创建微博模型
                guard let model = WBStatus.yy_model(with: dict)
                    else {
                    continue
                }
                
                let statusViewModel = WBStatusViewModel.init(model: model)
                array.append(statusViewModel)
            }
            
            print("下拉获取到 \(array.count)条微博 \(array)")
            
            //2拼接数据
            if !pullup {
                //下拉
                self.status = array + self.status
            } else {
                //上拉
                self.status = self.status + array
            }
            
            //判断上拉刷新数据量 为0, 上拉刷新错误次数加一
            if pullup && array.count == 0{
                self.pullupErrorTimes += 1
                //3完成回调
                completion(isSuccess, false)
            } else {
                self.cacheSingleImage(list: array, finished: completion)
                //3完成回调
//                completion(isSuccess, true)
            }
            
        }
        
    }
    
    /// 缓存本次下载微博数据数组中的单张图像
    private func cacheSingleImage(list: [WBStatusViewModel], finished:@escaping (_ isSuccess: Bool, _ shouldRefresh: Bool)->()) {
        //A 调度组
        let group = DispatchGroup()
        
        // 记录图像长度
        var length : Int = 0
        
        // 遍历数组 查找微博数据中 单张图片 进行缓存
        for viewModel in list {
            //1 遍历图像数量
            if viewModel.picURLs?.count != 1 {
                continue
            }
            
            //2 代码执行到此 数组中有且仅有一张图片
            guard let pic = viewModel.picURLs![0].thumbnail_pic,
                let url = URL(string: pic)
                else {
                continue
            }
            
            print("要缓存的URL是 \(url)")
            
            //B 入组
            group.enter()
            
            //3 下载
            // 1) downloadImage 是 SDWebImage 的核心方法
            // 2) 图像下载完成之后 会自动保存在沙盒中 文件路径是 URL 的 MD5
            // 3) 如果沙盒已经存在缓存的图像 后续使用 SD 通过 URL 加载图像 都会加载本地沙盒地图像
            // 4) 不会发起网络请求 同时 回调方法 同样会调用!
            // 5) 方法还是同样的方法 调用还是同样的调用 不过内部不会再次调用发起网络请求!
//            SDWebImageManager.shared.imageLoader.downloadImage(with: url, options: [], progress: nil, completed: { (image, _, _, _) in
//                //将图像转换成二进制数据
//                if let image = image,
//                    let data = UIImagePNGRepresentation(image) {
//                    length += data.count
//                    viewModel.updateSignleImageSize(image: image)
//                }
//                print("缓存的图像是 \(String(describing: image)) 长度是 \(length)")
//
//                //C 出组 在回调最后一句 调用
//                group.leave()
//            })
            SDWebImageManager.shared.imageLoader.requestImage(with: url, options: [], context: [:], progress: nil) { (image, _, _, _) in
                //将图像转换成二进制数据
                if let image = image,
                    let data = image.pngData() {
                    length += data.count
                    viewModel.updateSignleImageSize(image: image)
                }
                print("缓存的图像是 \(String(describing: image)) 长度是 \(length)")

                //C 出组 在回调最后一句 调用
                group.leave()
            }
            
        }
        
        //D 监听 调度组情况
        group.notify(queue: DispatchQueue.main) {
            print("图像缓存完成 \(length / 1025) K")
            
            //执行闭包回调
            finished(true, true)
        }
        
        
    }
    
    
}
